<template>
  <div class="relation" ref="myPage">
    <audio
      id="audio"
      hidden
      controls="controls"
      src="../../assets/warning.mp3"
      ref="audio"
    ></audio>
    <!-- 图谱 -->
    <div class="right-content">
      <RelationGraph
        ref="seeksRelationGraph"
        :options="userGraphOptions"
        :on-node-click="showNodeMenus"
        :on-line-click="onLineClick"
      >
        <div slot="node" slot-scope="{ node }">
          <div
            style="
              height: 50px;
              border-radius: 50%;
              cursor: pointer;
              display: flex;
              justify-content: center;
              align-items: center;
            "
            @mouseover="onNodeOver(node, $event)"
            @mouseout="nodeSlotOut(node, $event)"
          >
            <svg-icon
              style="color: #888888; width: 50px; height: 50px"
              :iconClass="node.data.icon ? node.data.icon : 'icon-question'"
            ></svg-icon>
          </div>
          <div
            style="
              color: #868b97;
              font-size: 16px;
              position: absolute;
              width: 70px;
              height: 20px;
              margin-left: -10px;
              line-height: 11px;
              margin-top: 2px;
              font-size: 10px;
              text-align: center;
              transform: scale(0.8);
              background-color: transparent;
              overflow: hidden; /* 限制文本的显示范围 */
              white-space: nowrap; /* 防止文本换行 */
              text-overflow: ellipsis; /* 超出显示省略号 */
            "
          >
            {{ node.text }}
          </div>
        </div>
      </RelationGraph>
    </div>

    <el-dialog title="新增联系" :visible.sync="addFormVisible">
      <el-form :model="addForm" label-width="80px">
        <el-form-item label="源主机">
          <el-select
            v-model="addForm.nmSourceHostid"
            placeholder="请选择源主机"
            disabled
          >
            <el-option
              v-for="item in fetch_Data"
              :key="item.hostid"
              :label="item.host"
              :value="item.hostid"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="目标主机">
          <el-select
            v-model="addForm.nmDestHostid"
            placeholder="请选择目标主机"
          >
            <el-option
              v-for="item in fetch_Data"
              :key="item.hostid"
              :label="item.host"
              :value="item.hostid"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="联系名称">
          <el-input
            v-model="addForm.nmAssociationName"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="addForm.remark" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="addRelation()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  getTopologyListApi,
  getTopologyBuildApi,
  getTopologyDelApi,
  getTopologyHostApi,
} from "@/api/dataPresentation/topologicalGraph";
import RelationGraph from "relation-graph";
export default {
  name: "SeeksRelationGraphDemo",
  components: { RelationGraph },
  data() {
    return {
      addFormVisible: false,
      addForm: {
        nmAssociationName: "",
        nmSourceHostid: null,
        nmDestHostid: "",
        nmSouceHostip: "",
        nmDestHostip: "",
        remark: "",
      },
      g_loading: true,
      //配置
      userGraphOptions: {
        backgrounImage: "",
        backgrounImageNoRepeat: true,
        layouts: [
          {
            label: "手工",
            layoutName: "fixed",
            layoutClassName: "seeks-layout-fixed",
            // 'defaultJunctionPoint': 'border'
          },
        ],
        defaultNodeBorderWidth: 0,
        defaultNodeShape: 0,
        defaultFocusRootNode: false,
        allowShowMiniNameFilter: false,
        defaultJunctionPoint: "lr",
        defaultLineShape: 2,
        defaultNodeColor: "#FFFFFF", //默认的节点背景颜色
        defaultNodeFontColor: "#868b97", //默认的节点文字颜色
        defaultNodeBorderColor: "#c4c4c6", //默认的节点边框颜色
        // defaultNodeBorderWidth: 1, //默认的节点边框粗细（像素）
        defaultNodeWidth: 50, //默认的节点宽度
        defaultNodeHeight: 50, //默认的节点高度
        // allowShowMiniToolBar: false,
      },
      //请求的数据
      fetch_Data: [],
      //设置图标
      icon_Set: {
        服务器: [
          "177.181.2.1",
          "177.181.2.2",
          "177.181.2.3",
          "177.181.2.4",
          "177.181.2.5",
          "177.181.2.6",
          "177.181.2.7",
          "177.181.2.8",
          "177.181.2.9",
          "177.181.2.10",
          "177.181.2.11",
          "177.181.2.12",
          "177.181.2.13",
          "177.181.2.14",
          "177.181.2.15",
          "177.181.2.16",
          "177.181.2.17",
          "177.181.2.18",
          "177.181.2.19",
          "177.181.2.20",
          "177.181.2.21",
          "177.181.2.22",
          "177.181.2.23",
          "177.181.2.24",
          "177.181.2.25",
          "177.181.2.26",
          "177.181.2.27",
          "177.181.2.28",
          "177.181.2.29",
          "177.181.2.30",
          "177.181.2.31",
          "177.181.2.32",
          "177.181.2.33",
          "177.181.2.34",
          "177.181.2.35",
          "177.181.2.36",
          "177.181.2.37",
          "177.181.2.38",
          "177.181.2.39",
          "177.181.2.40",
          "177.181.2.41",
          "177.181.2.42",
          "177.181.2.43",
          "177.181.2.44",
          "177.181.2.45",
          "177.181.2.46",
          "177.181.2.47",
          "177.181.2.48",
          "177.181.2.49",
          "177.181.2.50",
          "177.181.2.51",
          "177.181.2.52",
          "177.181.2.53",
          "177.181.2.54",
          "177.181.2.55",
          "177.181.2.56",
          "177.181.2.57",
          "177.181.2.58",
          "177.181.2.59",
          "177.181.2.60",
          "177.181.2.61",
          "177.181.2.62",
          "177.181.2.63",
          "177.181.2.64",
          "177.181.2.65",
          "177.181.2.66",
          "177.181.2.67",
          "177.181.2.68",
          "177.181.2.69",
          "177.181.2.70",
          "177.181.2.71",
          "177.181.2.72",
          "177.181.2.73",
          "177.181.2.74",
          "177.181.2.75",
          "177.181.2.76",
          "177.181.2.77",
          "177.181.2.78",
          "177.181.2.79",
          "177.181.2.80",
          "177.181.2.81",
          "177.181.2.82",
          "177.181.2.83",
          "177.181.2.84",
          "177.181.2.85",
          "177.181.2.86",
          "177.181.2.87",
          "177.181.2.88",
          "177.181.2.89",
          "177.181.2.90",
          "177.181.2.91",
          "177.181.2.92",
          "177.181.2.93",
          "177.181.2.94",
          "177.181.2.95",
          "177.181.2.96",
          "177.181.2.97",
          "177.181.2.98",
          "177.181.2.99",
          "177.181.2.100",
          "177.181.2.101",
          "177.181.2.102",
          "177.181.2.103",
          "177.181.2.104",
          "177.181.2.105",
          "177.181.2.106",
          "177.181.2.107",
          "177.181.2.108",
          "177.181.2.109",
          "177.181.2.110",
          "177.181.2.111",
          "177.181.2.112",
          "177.181.2.113",
          "177.181.2.114",
          "177.181.2.115",
          "177.181.2.116",
          "177.181.2.117",
          "177.181.2.118",
          "177.181.2.119",
          "177.181.2.120",
          "177.181.2.121",
          "177.181.2.122",
          "177.181.2.123",
          "177.181.2.124",
          "177.181.2.125",
          "177.181.2.126",
          "177.181.2.127",
          "177.181.2.128",
          "177.181.2.129",
          "177.181.2.130",
          "177.181.2.131",
          "177.181.2.132",
          "177.181.2.133",
          "177.181.2.134",
          "177.181.2.135",
          "177.181.2.138",
          "177.181.2.139",
          "177.181.2.140",
          "177.181.2.141",
          "177.181.2.142",
          "177.181.1.47",
          "177.181.1.48",
          "177.181.1.49",
          "177.181.1.50",
          "177.181.1.51",
          "177.181.2.136",
          "177.181.2.137",
          "177.181.4.1",
          "177.181.4.2",
          "177.181.4.3",
          "177.181.4.4",
          "177.181.3.43",
          "177.181.4.5",
          "177.181.4.6",
          "177.181.4.7",
          "177.181.4.8",
          "177.181.4.9",
          "177.181.4.10",
          "177.181.4.11",
          "177.181.4.12",
          "177.181.4.13",
          "177.181.4.14",
          "177.181.4.15",
          "177.181.4.16",
          "177.181.4.17",
          "177.181.4.18",
          "177.181.4.19",
          "177.181.4.20",
          "177.181.4.21",
          "177.181.4.22",
          "177.181.4.23",
          "177.181.4.24",
          "177.181.4.25",
          "177.181.4.26",
          "177.181.4.27",
          "177.181.4.28",
          "177.181.4.29",
          "177.181.4.30",
          "177.181.4.31",
          "177.181.4.32",
          "177.181.4.33",
          "177.181.4.34",
          "177.181.4.35",
          "177.181.4.36",
          "177.181.4.37",
          "177.181.4.38",
          "177.181.4.39",
          "177.181.4.40",
          "177.181.4.41",
          "177.181.3.40",
          "177.181.3.41",
          "177.181.3.42",
        ],

        路由器: ["177.181.1.1", "177.181.1.2", "177.181.3.1", "177.181.3.2"],

        负载均衡: ["177.181.1.3", "177.181.1.4", "177.181.3.5", "177.181.3.6"],

        防火墙: [
          "177.181.1.7",
          "177.181.1.8",
          "177.181.1.9",
          "177.181.1.10",
          "177.181.1.11",
          "177.181.1.12",
          "177.181.1.13",
          "177.181.1.14",
          "177.181.1.15",
          "177.181.3.9",
          "177.181.3.10",
          "177.181.3.11",
          "177.181.3.12",
          "177.181.3.13",
          "177.181.3.14",
          "177.181.3.15",
        ],

        交换机: [
          "177.181.1.16",
          "177.181.1.17",
          "177.181.1.18",
          "177.181.1.19",
          "177.181.1.20",
          "177.181.1.21",
          "177.181.1.22",
          "177.181.1.23",
          "177.181.1.24",
          "177.181.1.25",
          "177.181.1.26",
          "177.181.1.27",
          "177.181.1.28",
          "177.181.1.29",
          "177.181.1.253",
          "177.181.1.254",
          "177.181.1.32",
          "177.181.1.33",
          "177.181.1.34",
          "177.181.1.35",
          "177.181.1.36",
          "177.181.1.37",
          "177.181.3.16",
          "177.181.3.17",
          "177.181.3.18",
          "177.181.3.19",
          "177.181.3.20",
          "177.181.3.21",
          "177.181.3.253",
          "177.181.3.254",
          "177.181.3.24",
          "177.181.3.25",
          "177.181.3.26",
        ],

        分光器: [
          "177.181.1.43",
          "177.181.1.44",
          "177.181.3.36",
          "177.181.3.37",
        ],

        分流器: [
          "177.181.1.45",
          "177.181.1.46",
          "177.181.3.38",
          "177.181.3.39",
        ],

        IPS: ["177.181.1.5", "177.181.1.6", "177.181.3.7", "177.181.3.8"],
      },
    };
  },
  created() {
    this.getList();
  },
  mounted() {
    // this.setGraphData();
  },
  methods: {
    async getList() {
      let res = await getTopologyHostApi();
      let { code, data } = res;
      if (code == 200) {
        this.fetch_Data = data;
        this.setGraphData();
      }
    },
    hoverStyle() {
      document.querySelector(".allModels").style =
        "padding: 2px; border-radius: 2px;cursor: pointer;";
    },
    // 鼠标移入节点
    onNodeOver(nodeObject, $event) {
      const allLinks = this.$refs.seeksRelationGraph.getLinks();
      allLinks.forEach((link) => {
        // 还原所有样式
        link.relations.forEach((line) => {
          line.color = "#c3cdd7";
          line.fontColor = "#868b97";
          line.lineWidth = 1;
        });
      });
      // 让与{nodeObject}相关的所有连线高亮
      allLinks
        .filter(
          (link) => link.fromNode === nodeObject || link.toNode === nodeObject
        )
        .forEach((link) => {
          link.relations.forEach((line) => {
            line.data.orignColor = line.color;
            line.data.orignFontColor = line.fontColor || line.color;
            line.data.orignLineWidth = line.lineWidth || 1;
            line.color = "#409eff";
            line.fontColor = "#409eff";
            line.lineWidth = 1.5;
          });
        });
      // 有时候更改一些属性后，并不能马上同步到视图，这需要以下方法让视图强制根据数据同步到最新
      this.$refs.seeksRelationGraph.getInstance().dataUpdated();
    },
    //鼠标移出节点
    nodeSlotOut(nodeObject) {
      const allLinks = this.$refs.seeksRelationGraph.getLinks();
      allLinks.forEach((link) => {
        // 还原所有样式
        link.relations.forEach((line) => {
          line.color = "#c3cdd7";
          line.fontColor = "#869b97";
          line.lineWidth = 1;
        });
      });
      // 让与{nodeObject}相关的所有连线高亮
      allLinks
        .filter(
          (link) => link.fromNode === nodeObject || link.toNode === nodeObject
        )
        .forEach((link) => {
          link.relations.forEach((line) => {
            line.data.orignColor = line.color;
            line.data.orignFontColor = line.fontColor || line.color;
            line.data.orignLineWidth = line.lineWidth || 1;
            line.color = "#c3cdd7";
            line.fontColor = "#868b97";
            line.lineWidth = 1;
          });
        });
      // 有时候更改一些属性后，并不能马上同步到视图，这需要以下方法让视图强制根据数据同步到最新
      this.$refs.seeksRelationGraph.getInstance().dataUpdated();
    },
    // 线条点击
    onLineClick(lineObject, linkObject, $event) {
      console.log(lineObject);
      // console.log(linkObject);
      // this.dialogFormVisible = true;
      this.$notify({
        title: "点击连线：",
        type: "success",
        message:
          "点击了线:" +
          linkObject.fromNode.text +
          " to " +
          linkObject.toNode.text,
      });
      this.$confirm("此操作将永久删除该联系, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(async () => {
        let res = await getTopologyDelApi(lineObject.data.nmHostAssociationId);
        let { code, msg } = res;
        if (code == 200) {
          this.$message.success(msg);
          this.getList();
        } else {
          this.$message.errpr(msg);
        }
      });
    },
    //点击节点
    showNodeMenus(nodeObject, $event) {
      // console.log(nodeObject);
      (this.addForm = {
        nmAssociationName: "",
        nmSourceHostid: nodeObject.id,
        nmDestHostid: "",
        nmSouceHostip: nodeObject.data.ip,
        nmDestHostip: "",
        remark: "",
      }),
        (this.addFormVisible = true);
    },
    //添加关系
    async addRelation() {
      this.fetch_Data.forEach((item) => {
        if (this.addForm.nmDestHostid == item.hostid) {
          this.addForm.nmDestHostip = item.ip;
        }
      });
      let res = await getTopologyBuildApi(this.addForm);
      let { code, msg } = res;
      if (code == 200) {
        this.$message.success(msg);
        this.addFormVisible = false;
        this.getList();
      } else {
        this, $message.errpr(msg);
      }
    },
    //渲染图像
    setGraphData() {
      // 手工设置节点的坐标
      const _center = {
        x: -400,
        y: -250,
      };
      const graphData = {
        rootId: "root",
        nodes: [],
        lines: [],
      };

      let built_in_y = _center.y - 100;
      this.fetch_Data.forEach((item) => {
        if (item.available == 2) {
          let oAudio = document.querySelector("#audio");
          oAudio.loop = true;
          oAudio.play();
        }
        //在这里根据主机ip判断类型，加icon图标
        let icon = ""; //可以默认一个
        for (const key in this.icon_Set) {
          const element = this.icon_Set[key];
          const Index = element.findIndex((ip) => ip == item.ip);
          if (Index != -1) {
            switch (key) {
              case "服务器":
                icon = "网络服务器";
                break;
              case "路由器":
                icon = "路由器";
                break;
              case "负载均衡":
                icon = "负载均衡";
                break;
              case "防火墙":
                icon = "防火墙";
                break;
              case "交换机":
                icon = "交换机";
                break;
              case "分光器":
                icon = "分光器";
                break;
              case "分流器":
                icon = "分流器";
                break;
              case "IPS":
                icon = "IPS";
                break;
            }
          }
        }
        //
        graphData.nodes.push({
          ...item,
          id: item.hostid,
          text: item.host,
          styleClass:
            item.available == 2
              ? "my-node-flash-style"
              : item.available == 0
              ? "my-node-flash-style1"
              : "",
          data: {
            icon: icon,
            ip: item.ip,
          },
          x: item.built_in ? -300 : _center.x,
          y: item.built_in ? (built_in_y += 100) : _center.y,
        });
        if (_center.x < 1000) !item.built_in && (_center.x += 150);
        else {
          _center.x = -400;
          _center.y += 150;
        }
        if (item.hostAssociations && item.hostAssociations.length)
          item.hostAssociations.forEach((to) =>
            graphData.lines.push({
              text: to.nmAssociationName,
              from: to.nmSourceHostid.toString(),
              to: to.nmDestHostid.toString(),
              data: {
                nmHostAssociationId: to.nmHostAssociationId,
              },
            })
          );
      });
      this.$refs.seeksRelationGraph.setJsonData(
        graphData,
        (graphInstance) => {}
      );
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" >
.my-node-style {
  background-color: #00ced1 !important;
  /** 通过自定义样式设置节点颜色需要加 !important **/
}

.my-node-style:hover {
  background-color: #ff0000 !important;
}

@keyframes myFlash {
  from {
    opacity: 1;
  }

  50% {
    opacity: 0.4;
  }

  to {
    opacity: 1;
  }
}

@-webkit-keyframes myFlash {
  from {
    opacity: 1;
  }

  50% {
    opacity: 0.4;
  }

  to {
    opacity: 1;
  }
}

.my-node-flash-style {
  animation: myFlash 600ms infinite;
  -webkit-animation: myFlash 600ms infinite;
  box-shadow: 0px 0px 15px 5px red;
  // background-color: #ff0000;
}

.my-node-flash-style1 {
  animation: myFlash 600ms infinite;
  -webkit-animation: myFlash 600ms infinite;
  box-shadow: 0px 0px 15px 5px rgb(252, 172, 0);
  // background-color: #ff0000;
}

.relation {
  height: calc(100vh - 105px);
  display: flex;
  justify-content: space-between;

  // .left-menu {
  //   width: 15%;
  //   background-color: #ffffff;
  //   padding: 10px;
  //   box-sizing: border-box;
  //   border-right: 2px solid #e4e0e0;
  // }

  .right-content {
    width: 100%;
  }
}
</style>